from math import sqrt, pow

from PyQt6.QtCore import pyqtSignal, QPointF, Qt, QRect, QPoint
from PyQt6.QtGui import QPainter, QPen, QAction
from PyQt6.QtWidgets import QLabel, QMenu


class PictureLabel(QLabel):

    # 信号：鼠标移动
    mousemoved = pyqtSignal(QPointF)
    # 信号：鼠标释放
    mousereleased = pyqtSignal(QPointF, QPointF)
    # 拖拽信号
    point1 = QPointF(0, 0)  # 按下点
    point2 = QPointF(0, 0)  # 释放点
    flag = False            # 是否拖拽

    """
    图片显示控件
    """
    def __init__(self, menu_action: QAction, parent, main):
        super(PictureLabel, self).__init__(parent)
        self.setScaledContents(True)
        self.setMouseTracking(True)
        self.mainWindow = main
        # menu
        self.contextMenu = QMenu(self)
        self.contextMenu.addAction(menu_action)
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

    def region_available(self):
        """
        检查是否存在选区
        :return: 是否存在选区
        """
        x1 = int(self.point1.x())
        y1 = int(self.point1.y())
        x2 = int(self.point2.x())
        y2 = int(self.point2.y())
        return x1 != x2 and y1 != y2

    def selected_region(self):
        """
        获取当前选区
        :return: 选区左上-右下点
        """
        x1 = self.point1.x()
        y1 = self.point1.y()
        x2 = self.point2.x()
        y2 = self.point2.y()
        return QPointF(min(x1, x2), min(y1, y2)), QPointF(max(x1, x2), max(y1, y2))

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.flag = True
            self.point1 = event.position()

    def mouseMoveEvent(self, event):
        self.point2 = event.position()
        if self.flag:
            self.update()
        self.mousemoved.emit(self.point2)

    def mouseReleaseEvent(self, event):
        self.flag = False
        region_mode = self.mainWindow.region_mode()
        if region_mode != '' and self.region_available():
            if region_mode == 'circle':
                # 取外接矩形端点
                x1 = self.point1.x()
                y1 = self.point1.y()
                x2 = self.point2.x()
                y2 = self.point2.y()
                r = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
                self.point1 = QPointF(x1 - r, y1 - r)
                self.point2 = QPointF(x1 + r, y1 + r)

            self.mousereleased.emit(self.point1, self.point2)

    def paintEvent(self, event):
        super().paintEvent(event)
        # 绘制选区
        region_mode = self.mainWindow.region_mode()
        if region_mode != '' and self.region_available():
            painter = QPainter(self)
            painter.setPen(QPen(Qt.GlobalColor.cyan, 1.5, Qt.PenStyle.DashDotLine))
            if region_mode == 'circle':
                x1 = self.point1.x()
                y1 = self.point1.y()
                x2 = self.point2.x()
                y2 = self.point2.y()
                r = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
                painter.drawEllipse(int(x1 - r), int(y1 - r), int(r * 2), int(r * 2))
            elif region_mode == 'rect':
                painter.drawRect(int(self.point1.x()), int(self.point1.y()),
                                 int(abs(self.point1.x() - self.point2.x())),
                                 int(abs(self.point1.y() - self.point2.y())))

    def showContextMenu(self, point):
        self.contextMenu.move(self.mapToGlobal(point))
        self.contextMenu.show()
